<template>
  <div :class="`${props.classPrefix}-box`">
    <div
      v-for="(item, index) in props.lotteryList"
      :class="[`${props.classPrefix}-item`, { active: state.curIndex === index }]"
    >
      <template v-if="index !== 4">
        <img v-if="item.pic" :src="item.pic" class="pic" alt="" />
        <!-- <p class="text">{{ item.name }}</p> -->
      </template>
      <div v-else @click="start()">
        <slot name="lotteryBtn" :itemData="item"> </slot>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { Ref, ref, reactive, computed, watchEffect } from 'vue';
  const emit = defineEmits(['end']);
  const props = withDefaults(
    defineProps<{
      // 数据列表
      lotteryList: { pic: string; name?: string }[];
      // 中奖id
      winId: number;
      // 抽奖初始转动速度
      initSpeed: number;
      // 抽奖最快转动速度
      fastSpeed: number;
      // 抽奖最慢转动速度
      slowSpeed: number;
      // 基本圈数
      baseCircles: number;
      // 样式类名前缀
      classPrefix: string;
    }>(),
    {
      lotteryList: () => [],
      // 中奖id
      winId: 0,
      // 抽奖转动速度
      initSpeed: 300,
      fastSpeed: 100,
      slowSpeed: 600,
      // 基本圈数
      baseCircles: 4,
    }
  );

  const state = reactive({
    // 当前位置
    curIndex: -1,
    // 已跑次数
    curStep: 0,
    // 转动速度
    speed: 0,
    // 是否正在抽奖
    isRunning: false,
  });

  // 顺时针跑动顺序索引
  const lotterySort = [0, 1, 2, 5, 8, 7, 6, 3];

  // 总跑动步数
  const totalSteps = computed(() => {
    return props.baseCircles * 8 + lotterySort.indexOf(props.winId);
  });

  const start = () => {
    // 重置跑动状态
    if (!state.isRunning) {
      state.isRunning = true;
      state.curStep = 0;
      state.speed = props.initSpeed;
      startRun();
    }
  };

  const timer: Ref<ReturnType<typeof setTimeout> | null> = ref(null);

  const startRun = () => {
    // 延时器的速度要动态调节
    timer.value && clearTimeout(timer.value);

    // console.log(`已走步数=${state.curStep}, 执行总步数=${totalSteps.value}`);

    // 已走步数超过要执行总步数, 则停止
    if (state.curStep > totalSteps.value) {
      state.isRunning = false;
      return emit('end');
    }

    // 高亮抽奖格子序号
    state.curIndex = lotterySort[state.curStep % 8];
    // 速度调整
    state.speed = calcSpeed(state.speed);

    timer.value = setTimeout(() => {
      state.curStep++;
      startRun();
    }, state.speed);
  };

  // 需要加速的前段步数
  const frontSteps = Math.floor(props.baseCircles * 8 * (1 / 3));
  // 需要减速的后段步数
  const midSteps = Math.floor(totalSteps.value * (5 / 6));

  // 计算速度
  const calcSpeed = (speed: number) => {
    // 最快最慢速度
    const { fastSpeed, slowSpeed } = props;
    // 前段加速，中段匀速，后段减速
    if (state.curStep < frontSteps && speed > fastSpeed) {
      speed = speed - Math.floor((props.initSpeed - fastSpeed) / frontSteps);
    } else if (state.curStep > midSteps && speed < slowSpeed) {
      // 减速不一定要减速到最慢速度，优先保证动画效果看着协调
      speed = speed + Math.floor((slowSpeed - fastSpeed) / frontSteps / 5);
    }
    return speed;
  };
</script>
